from flask import jsonify, request
from . import questionBank_bp
from models import Question, Bank, QuestionBank, Choice, Answer, Exercise
from app.extensions import db


@questionBank_bp.route('/')
def index():
    return jsonify(u"this is questionBank url prefix")


@questionBank_bp.route('allQuestionBanks', methods=["GET"])
def get_question_banks():
    try:

        all_banks = (
            db.session.query(Bank)
            .order_by(Bank.bank_id.desc())
            .all()
        )

        banks_with_questions = append_questions_to_bank(all_banks)

        return jsonify(banks_with_questions), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({'status': 'error', 'message': str(e)}), 500


@questionBank_bp.route('questionBanksByUser', methods=["GET"])
def get_question_banks_by_user():
    try:
        user_id = request.args.get('user_id')
        if not user_id:
            return jsonify({'error': 'User ID is required'}), 400

        all_banks = (
            db.session.query(Bank)
            .filter(Bank.bank_user == user_id)  # 检测用户ID
            .order_by(Bank.bank_id.desc())
            .all()
        )

        banks_with_questions = append_questions_to_bank(all_banks)

        return jsonify(banks_with_questions), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({'status': 'error', 'message': str(e)}), 500


def append_questions_to_bank(all_banks):
    banks_with_questions = []

    for bank in all_banks:
        questions_query = (
            db.session.query(Question)
            .join(QuestionBank, QuestionBank.question_id == Question.question_id)
            .filter(QuestionBank.bank_id == bank.bank_id)
            .order_by(Question.question_id.asc())  # 按升序排列问题
            .all()
        )

        questions = [question.question_text for question in questions_query]

        banks_with_questions.append({
            "bank_id": bank.bank_id,
            "bank_name": bank.bank_name,
            "questions": questions,
        })

    return banks_with_questions



@questionBank_bp.route('/getBankDetail/<int:bank_id>', methods=["GET"])
def get_bank_detail(bank_id):
    try:
        bank = db.session.query(Bank).get(bank_id)
        if not bank:
            return jsonify({'error': 'Bank not found'}), 404

        questions_query = (
            db.session.query(Question)
            .join(QuestionBank, QuestionBank.question_id == Question.question_id)
            .filter(QuestionBank.bank_id == bank_id)
            .order_by(Question.question_id.asc())  # 按升序排列问题
            .all()
        )

        exercises_count = (
            db.session.query(Exercise)
            .filter(Exercise.exercise_bank == bank_id)
            .count()
        )

        questions_detail = []
        correct_questions_count = 0  # 总正确作答数
        total_questions_count = 0  # 总作答数

        for index, question in enumerate(questions_query, start=1):  # 从1开始编号
            choices_query = db.session.query(Choice).filter_by(question_id=question.question_id).all()
            choices = [choice.choice_text for choice in choices_query]
            correct_choice_id = next((choice.choice_id for choice in choices_query if choice.is_correct == 1), None)
            correct_choice_number = {choice.choice_id: idx + 1 for idx, choice in enumerate(choices_query)}.get(
                correct_choice_id, 0)

            total_answers_count = db.session.query(Answer).filter_by(question_id=question.question_id).count()
            correct_answers_count = db.session.query(Answer).filter_by(question_id=question.question_id,
                                                                       choice=correct_choice_id).count()
            correct_rate = (correct_answers_count / total_answers_count) * 100 if total_answers_count > 0 else 0

            questions_detail.append({
                'number': index,  # 题目编号
                'question_text': question.question_text,
                'description': question.description,  # 答案解析
                'choices': choices,  # 问题选项
                'correct_answer': correct_choice_number - 1,  # 正确答案选项的下标，0=A
                'total_answers_count': total_answers_count,  # 作答人数
                'correct_rate': round(correct_rate, 2)  # 正确率
            })

            correct_questions_count += correct_answers_count
            total_questions_count += total_answers_count

        return jsonify({
            'bank_id': bank.bank_id,
            'bank_name': bank.bank_name,
            'questions': questions_detail,
            'exercises_count': exercises_count,
            'average_correct_rate': round((correct_questions_count / total_questions_count) * 100,
                                          2) if total_questions_count > 0 else 0
        }), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


def get_exercise_accuracy(exercise_id):
    answers = db.session.query(Answer).filter_by(exercise_id=exercise_id).all()
    if not answers:
        return None
    total_answers = len(answers)
    correct_answers = 0
    for answer in answers:
        if answer.choice is not None:
            choice = db.session.query(Choice).filter_by(choice_id=answer.choice).first()
            if choice and choice.is_correct:
                correct_answers += 1
    accuracy = correct_answers / total_answers if total_answers > 0 else 0
    return accuracy


@questionBank_bp.route('/getBankExercise/<int:bank_id>', methods=["GET"])
def get_exercises_for_bank(bank_id):
    try:
        exercises = db.session.query(Exercise).filter_by(exercise_bank=bank_id).all()
        results = []
        for exercise in exercises:
            accuracy = get_exercise_accuracy(exercise.exercise_id)
            results.append({
                'exercise_id': exercise.exercise_id,
                'finished_time': exercise.exercise_finish_datetime,
                'correct_rate': accuracy if accuracy is not None else 0  # 转换为百分比形式
            })
        return jsonify(results), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'status': 'error', 'message': str(e)}), 500
